package com.isyscore.os.metadata.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Strings;
import com.isyscore.os.core.exception.DataFactoryException;
import com.isyscore.os.metadata.common.CommonService;
import com.isyscore.os.metadata.dao.MetricMeasureMapper;
import com.isyscore.os.metadata.model.dto.MetricMeasureDTO;
import com.isyscore.os.metadata.model.entity.MetricMeasure;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.isyscore.os.core.exception.ErrorCode.MEASURE_AGG_INCONSISTENCY;
import static java.util.Collections.emptyList;

/**
 * <p>
 * 保存指标的所涉及的度量值，以及度量值所对应的聚合方式 服务实现类
 * </p>
 *
 * @author wany
 * @since 2021-10-12
 */
@Service
public class MetricMeasureService extends CommonService<MetricMeasureMapper, MetricMeasure> {

    public List<MetricMeasure> getMeasuresByMetricId(Long metricId) {
        LambdaQueryWrapper<MetricMeasure> qw = new LambdaQueryWrapper<>();
        qw.eq(MetricMeasure::getMetricRefId, metricId);
        return this.list(qw);
    }

    public void saveMetricMeasure(Long metricId, List<MetricMeasureDTO> measures) {
        this.deleteMetricMeasure(metricId);
        if (measures != null) {
            long aggMeasureCount = measures.stream().filter(m -> !Strings.isNullOrEmpty(m.getMeasureAggType())).count();
            if (aggMeasureCount != 0 && aggMeasureCount != measures.size()) {
                throw new DataFactoryException(MEASURE_AGG_INCONSISTENCY);
            }
            List<MetricMeasure> entities = measures.stream().map(MetricMeasureDTO::toEntity).collect(Collectors.toList());
            entities.forEach(e -> {
                e.setMetricRefId(metricId);
            });
            this.saveBatch(entities);
        }
    }

    public void deleteMetricMeasure(Long metricId) {
        LambdaQueryWrapper<MetricMeasure> qw = new LambdaQueryWrapper<>();
        qw.eq(MetricMeasure::getMetricRefId, metricId);
        this.remove(qw);
    }

    public void importData(List<MetricMeasure> measures) {
        if (measures.isEmpty()) {
            return;
        }
        Set<Long> ids = measures.stream().map(MetricMeasure::getMetricRefId).collect(Collectors.toSet());
        LambdaQueryWrapper<MetricMeasure> qw = new LambdaQueryWrapper<>();
        qw.in(MetricMeasure::getMetricRefId, ids);
        this.remove(qw);
        this.saveBatch(measures);
    }

    public List<MetricMeasure> getMeasuresByMetricIds(Set<Long> metricIds) {
        if (metricIds == null || metricIds.isEmpty()) {
            return emptyList();
        }
        LambdaQueryWrapper<MetricMeasure> qw = new LambdaQueryWrapper<>();
        qw.in(MetricMeasure::getMetricRefId, metricIds);
        return this.list(qw);
    }

}
